﻿#include "maincombineentrustwidget.h"
#include"CommUtil/comfunc.h"
#include<QMessageBox>
#include<QLineEdit>
#include"ufxconfig.h"

//#define __DETAILS


MainCombineEntrustWidget::MainCombineEntrustWidget(QWidget *parent) :
    QWidget(parent)
{
    setupViews();
    ///测试数据
    /*QStringList Items;
    Items<<"123";
    Items<<"123";
    Items<<"123";
    Items<<"123";
    Items<<"123";
    Items<<"123";
    Items<<"123";
    Items<<"123";
    Items<<"123";
    Items<<"123";

    QTreeWidgetItem* A = new QTreeWidgetItem(Items);
    A->setFlags(A->flags()|Qt::ItemIsEditable);
    //tree->editItem(item, 0);
    m_treeWidget->insertTopLevelItem(0,A);*/
}
bool MainCombineEntrustWidget::eventFilter(QObject *obj, QEvent *event){
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent* keyEvent = (QKeyEvent*)(event);
        emit SigkeyPressEvent(keyEvent);
        return true;
    } else {
        // standard event processing
        return QObject::eventFilter(obj, event);
    }
}

void MainCombineEntrustWidget::setupViews()
{
	m_treeWidget = new QTreeWidget;
	m_treeWidget->setAlternatingRowColors(true);

	//设定头项名称
	m_treeWidget->headerItem()->setText(0,QStringLiteral("用户代码"));
	m_treeWidget->headerItem()->setText(1,QStringLiteral("报单编号"));
	m_treeWidget->headerItem()->setText(2,QStringLiteral("本地报单编号"));
	m_treeWidget->headerItem()->setText(3,QStringLiteral("合约代码"));
	m_treeWidget->headerItem()->setText(4,QStringLiteral("买卖"));
	m_treeWidget->headerItem()->setText(5,QStringLiteral("开平"));
	m_treeWidget->headerItem()->setText(6,QStringLiteral("价格"));
	m_treeWidget->headerItem()->setText(7,QStringLiteral("委手"));
	m_treeWidget->headerItem()->setText(8,QStringLiteral("成手"));
	m_treeWidget->headerItem()->setText(9,QStringLiteral("状态"));
	m_treeWidget->headerItem()->setText(10,QStringLiteral("委托时间"));
	m_treeWidget->headerItem()->setText(11,QStringLiteral("套保标识"));
	m_treeWidget->headerItem()->setText(12,QStringLiteral("成交时间"));
#ifdef  __DETAILS
    m_treeWidget->headerItem()->setText(13,QStringLiteral("系统回报时间戳(毫秒)"));
    m_treeWidget->headerItem()->setText(14,QStringLiteral("交易所回报时间戳(毫秒)"));
#endif

	m_treeWidget->header()->setSectionsClickable(true);
	m_treeWidget->header()->setSectionsMovable(true);
	QFont font = m_treeWidget->header()->font();
	font.setBold(true);
    m_treeWidget->header()->setFont(font);

#ifdef  __DETAILS
    m_treeWidget->setColumnCount(15);
#else
    m_treeWidget->setColumnCount(13);
#endif
	m_treeWidget->setColumnWidth(0,100);
	m_treeWidget->setColumnWidth(1,100);
	m_treeWidget->setColumnWidth(2,100);
	m_treeWidget->setColumnWidth(3,120);
	m_treeWidget->setColumnWidth(4,100);
	m_treeWidget->setColumnWidth(5,100);
	m_treeWidget->setColumnWidth(6,100);
	m_treeWidget->setColumnWidth(7,100);
	m_treeWidget->setColumnWidth(8,100);
	m_treeWidget->setColumnWidth(9,100);
	m_treeWidget->setColumnWidth(10,100);
	m_treeWidget->setColumnWidth(11,100);
    m_treeWidget->setColumnWidth(12,100);
#ifdef  __DETAILS
    m_treeWidget->setColumnWidth(13,100);//系统回报时间戳
    m_treeWidget->setColumnWidth(14,100);//交易所回报时间戳
#endif
    QHBoxLayout* hboxlayout = new QHBoxLayout;
    Cancelbutton = new QPushButton(QStringLiteral("撤单"));
    CancelAllbutton = new QPushButton(QStringLiteral("全撤"));
    Cancelbutton->setFixedWidth(80);
    CancelAllbutton->setFixedWidth(80);

    hboxlayout->addWidget(Cancelbutton);
    hboxlayout->addWidget(CancelAllbutton);
    hboxlayout->addStretch();
    hboxlayout->addStretch();

    MainLayout = new QGridLayout(this);
    MainLayout->addLayout(hboxlayout,0,0);
    MainLayout->addWidget(m_treeWidget,1,0);

    MainLayout->setMargin(0);
    MainLayout->setSpacing(0);

    m_treeWidget->installEventFilter(this);
    connect(m_treeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(SlotItemDoubleClicked(QTreeWidgetItem*,int)));

    connect(this,SIGNAL(Sigrepaint()),this,SLOT(Slotrepaint()));

    connect(CancelAllbutton,SIGNAL(clicked()),this,SLOT(CancelAllOrders()));
    connect(Cancelbutton,SIGNAL(clicked()),this,SLOT(CancelOrder()));
    connect(m_treeWidget,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(CancelOrderDoubleClicked(QModelIndex)));

    QString HideCancelOrderButtomFlg = UFXConfig::getInstance()->GetString("FuncFlag","HideCancelOrderButtomFlg","0");
    if(HideCancelOrderButtomFlg == "1"){
        Cancelbutton->hide();
        CancelAllbutton->hide();
    }
}
void MainCombineEntrustWidget::Slotrepaint(){
    this->m_treeWidget->reset();
}
void MainCombineEntrustWidget::SlotChangeOrder(){
    // 编辑完成后,移除widget,还原树
    QTreeWidgetItem *curItem=m_treeWidget->currentItem();
    QLineEdit *edit=qobject_cast<QLineEdit*>(m_treeWidget->itemWidget(curItem,m_CurrColumn));
    if(!edit)
        return;

    QString text=edit->text();
    // 移除widget
    m_treeWidget->removeItemWidget(curItem,m_CurrColumn);
    // 还原值
    curItem->setText(m_CurrColumn,text);
}
void MainCombineEntrustWidget::SlotItemDoubleClicked(QTreeWidgetItem *item, int column){
    if (column == 6 || column == 7){    //价格 和 手数 可编辑
        m_CurrColumn = column;
        //item->setFlags(item->flags()|Qt::ItemIsEditable);

        QString value = item->text(column);
        //使用QTextEdit的信号
        QLineEdit *lineEdit=new QLineEdit(this);
        //QRegExp regx("^    (100000)    |    (400[.]{1,1}[0]{0,1})    |     ([1-3]{0,1}[0-9]{1,2})   |   ([1-3]{0,1}[0-9]{1,2}[.]{1,1}[0-9]{0,1})");
        //QValidator *validator = new QRegExpValidator(regx, lineEdit );
        QDoubleValidator *validator = new QDoubleValidator(0,100000,4,lineEdit);
        lineEdit->setValidator( validator );

        connect(lineEdit,SIGNAL(editingFinished()),this,SLOT(SlotChangeOrder()));
        m_treeWidget->setItemWidget(item,column,lineEdit);
        // 选中项
        m_treeWidget->setCurrentItem(item);
        // 设置默认值
        lineEdit->setText(value);
        lineEdit->setSelection(0,value.length());
        lineEdit->setFocus();
    }else{        //当双击的不是价格和手数的时候将flags中的可编辑属性去掉
        item->setFlags(item->flags()&~(Qt::ItemIsEditable));
    }
}
void MainCombineEntrustWidget::SlotHideCancelOrderButtonToggled(bool b){
    if(b){
        Cancelbutton->hide();
        CancelAllbutton->hide();
    }else{
        Cancelbutton->show();
        CancelAllbutton->show();
    }
}
void MainCombineEntrustWidget::SlotChangeOrder(int iChangeType){
    switch (iChangeType) {
    case 0://撤销选中单
        CancelOrder();
        break;
    case 1://撤销最后一个单
        CancelNewestOrder();
        break;
    case 2://撤销最早一个单
        CancelOldestOrder();
        break;
    case 3://按合约撤单
        break;
    case 4://按买卖撤单
        break;
    case 5://按合约及买卖撤单
        break;
    case 6://全部撤单
        CancelAllOrders();
        break;
    case 7://按对手价改单
        ChangeOrder(0);
        break;
    case 8://改价格
        ChangeOrder(1);
        break;
    case 9://改手数
        ChangeOrder(2);
        break;
    default:
        break;
    }
}
//////////////////////////////////////////
/// \brief MainCombineEntrustWidget::ChangeOrder
/// \param iChangeType 0 对手价改单 1 改价格 2 改手数
///
void MainCombineEntrustWidget::ChangeOrder(int iChangeType){
    int row = m_treeWidget->currentIndex().row();
    if(row == -1){
        QMessageBox::critical(this,QString("Error"),QStringLiteral("未选中有效委托单!"));
    }else{
        QTreeWidgetItem* Temp = m_treeWidget->topLevelItem(row);
        QString OrderStatus    = Temp->text(9);

        switch(iChangeType){
        case 0://对手价改单
            break;
        case 1:{//改价格
            SlotItemDoubleClicked(Temp,6);
            break;}
        case 2://改手数
            SlotItemDoubleClicked(Temp,7);
            break;
        default:
            break;
        }

        if(OrderStatus == QStringLiteral("已报") || OrderStatus ==QStringLiteral("部成")){
            CancelOrder(Temp->text(2),1);
            return;
        }
    }
}

void MainCombineEntrustWidget::CancelOrder(QString entrust_no,int CancelType){

    if(m_EntrustOrderMap.contains(entrust_no)){
        emit SigCancelOrder(m_EntrustOrderMap[entrust_no].ExchangeID,m_EntrustOrderMap[entrust_no].OrderSysID,CancelType);
    }
}

void MainCombineEntrustWidget::UpdateBatchOrder(CThostFtdcTradeField *pTrade){

    //ComFunc::OutputInfoMessage(QString(pTrade->OrderLocalID).toInt(),pTrade->InstrumentID,pTrade->OrderRef,THOST_FTDC_OST_AllTraded);

	m_UpdateMutex.lock();
    int iTopCnt = m_treeWidget->topLevelItemCount();
    for(int i = 0; i < iTopCnt; i ++){
        QTreeWidgetItem* Temp = m_treeWidget->topLevelItem(i);
        int iBatchNo    = Temp->text(2).toInt();
        QString ContractCode    = Temp->text(3);
        if(iBatchNo == QString(pTrade->OrderLocalID).toInt() && ContractCode != ""){//判断批量单号是否一致

			int i = Temp->text(8).toInt();

            Temp->setText(8,QString::number( pTrade->Volume + i));
            Temp->setText(12,QString( pTrade->TradeTime));

            int iEntrustCnt = Temp->text(7).toInt();//委托手数

            if(i + pTrade->Volume < iEntrustCnt){
                Temp->setText(9,QStringLiteral("部成"));
            }else if(i + pTrade->Volume == iEntrustCnt){
                Temp->setText(9,QStringLiteral("已成"));
            }
			m_UpdateMutex.unlock();
            emit Sigrepaint();
            return;
        }
    }
	m_UpdateMutex.unlock();
}
void MainCombineEntrustWidget::CancelOrderDoubleClicked(const QModelIndex &index){
    int row = index.row();
    QTreeWidgetItem* Temp = m_treeWidget->topLevelItem(row);
    QString OrderStatus    = Temp->text(9);

    if(OrderStatus == QStringLiteral("已报") || OrderStatus ==QStringLiteral("部成")){
        CancelOrder(Temp->text(1),2);
        return;
    }
}

void MainCombineEntrustWidget::CancelOrder(){
    int row = m_treeWidget->currentIndex().row();
    if(row == -1){
        QMessageBox::critical(this,QString("Error"),QStringLiteral("未选中有效委托单!"));
    }else{
		QTreeWidgetItem* Temp = m_treeWidget->topLevelItem(row);
		QString OrderStatus    = Temp->text(9);

		if(OrderStatus == QStringLiteral("已报") || OrderStatus ==QStringLiteral("部成")){
            CancelOrder(Temp->text(1),1);
			return;
		}
    }
}
void MainCombineEntrustWidget::CancelNewestOrder(){
	 int iTopCnt = m_treeWidget->topLevelItemCount();
	 for(int i = 0; i < iTopCnt; i ++){
		 QTreeWidgetItem* Temp = m_treeWidget->topLevelItem(i);
		 QString OrderStatus    = Temp->text(9);

         if(OrderStatus == QStringLiteral("已报") || OrderStatus ==QStringLiteral("部成")){
            CancelOrder(Temp->text(1),1);
			return;
		 }
	 }
 }
 void MainCombineEntrustWidget::CancelOldestOrder(){
	 int iTopCnt = m_treeWidget->topLevelItemCount();
	 for(int i = iTopCnt; i > 0; i--){
		 QTreeWidgetItem* Temp = m_treeWidget->topLevelItem(i-1);
		 QString OrderStatus    = Temp->text(9);

         if(OrderStatus == QStringLiteral("已报") || OrderStatus ==QStringLiteral("部成")){
             CancelOrder(Temp->text(1),1);
			 return;
		 }
	 }
 }
 void MainCombineEntrustWidget::CancelAllOrders(){
	 int iTopCnt = m_treeWidget->topLevelItemCount();
	 for(int i = 0; i < iTopCnt; i ++){
		 QTreeWidgetItem* Temp = m_treeWidget->topLevelItem(i);
		 QString OrderStatus    = Temp->text(9);

         if(OrderStatus == QStringLiteral("已报") || OrderStatus ==QStringLiteral("部成")){
             CancelOrder(Temp->text(1),1);
		 }
	 }
 }
void MainCombineEntrustWidget::AddUFTSystemRetTime(QString entrustno, QString time){
    if(m_MapUFTSystemRetTime.contains(entrustno)){
        m_MapUFTSystemRetTime[entrustno] = time;
    }else{
        m_MapUFTSystemRetTime.insert(entrustno,time);
    }
}

void MainCombineEntrustWidget::ShowBatchOrder(CThostFtdcOrderField *pOrder){
    QString currtime = ComFunc::OutputInfoMessage(QString(pOrder->OrderSysID).toInt(),pOrder->InstrumentID,
                                                  pOrder->OrderRef,pOrder->OrderStatus);

    if(QString(pOrder->OrderSysID) != ""){
        //将报单信息保存在Map中
        CThostFtdcOrderField oOrder;
        memcpy_s(&oOrder,sizeof(CThostFtdcOrderField),pOrder,sizeof(CThostFtdcOrderField));
        m_EntrustOrderMap.insert(QString(pOrder->OrderSysID),oOrder);
    }
	
	m_UpdateMutex.lock();

	int iTopCnt = m_treeWidget->topLevelItemCount();
	for(int i = 0; i < iTopCnt; i ++){
		QTreeWidgetItem* Temp = m_treeWidget->topLevelItem(i);
		int iBatchNo    = Temp->text(2).toInt();
		QString ContractCode    = Temp->text(3);
        if(iBatchNo == QString(pOrder->OrderLocalID).toInt() && ContractCode != ""){//判断批量单号是否一致
            Temp->setText(1,pOrder->OrderSysID);
            //状态
            switch(pOrder->OrderStatus){
            case    THOST_FTDC_OST_NotTouched:	Temp->setText(9,QStringLiteral("未报")); break;
            //case 	'1':	Temp->setText(9,QStringLiteral("待报"));break;
            case 	THOST_FTDC_OST_Touched:	//Temp->setText(9,QStringLiteral("已报"));break;
            case 	THOST_FTDC_OST_NoTradeQueueing:	Temp->setText(9,QStringLiteral("已报"));break;
            case 	THOST_FTDC_OST_NoTradeNotQueueing:	Temp->setText(9,QStringLiteral("部成待撤"));break;
            case 	THOST_FTDC_OST_PartTradedNotQueueing:	Temp->setText(9,QStringLiteral("部撤"));break;
            case 	THOST_FTDC_OST_Canceled:	Temp->setText(9,QStringLiteral("已撤"));break;
            case 	THOST_FTDC_OST_PartTradedQueueing:	Temp->setText(9,QStringLiteral("部成"));break;
            case 	THOST_FTDC_OST_AllTraded:	Temp->setText(9,QStringLiteral("已成"));break;
            case 	THOST_FTDC_OST_Unknown:	Temp->setText(9,QStringLiteral("废单"));break;
            }

			m_UpdateMutex.unlock();
            emit Sigrepaint();
            return;
		}
	}
	//显示在控件上
	QStringList Items;
    Items<<QString(pOrder->InvestorID)<<QString(pOrder->OrderSysID)<<QString(pOrder->OrderLocalID)<<QString(pOrder->InstrumentID);
	///买卖方向
    if (pOrder->Direction == THOST_FTDC_D_Buy){
		Items<<QStringLiteral("买入");
    } else if(pOrder->Direction == THOST_FTDC_D_Sell){
		Items<<QStringLiteral("卖出");
	}
    //开平
    switch(pOrder->CombOffsetFlag[0]){
    case THOST_FTDC_OF_Open:
        Items<<QStringLiteral("开仓");
        break;
    case THOST_FTDC_OF_Close:
        Items<<QStringLiteral("平仓");
        break;
    case THOST_FTDC_OF_ForceClose:
        Items<<QStringLiteral("强平");
        break;
    case THOST_FTDC_OF_CloseToday:
        Items<<QStringLiteral("平今");
        break;
    case THOST_FTDC_OF_CloseYesterday:
        Items<<QStringLiteral("平昨");
        break;
    case THOST_FTDC_OF_ForceOff:
        Items<<QStringLiteral("强减");
        break;
    case THOST_FTDC_OF_LocalForceClose:
        Items<<QStringLiteral("本地强平");
        break;
    default:
        break;
    }

	//委托价格
    Items<<QString::number(pOrder->LimitPrice);
	//委托数量
    Items<<QString::number(pOrder->VolumeTotal);
	//成交数量
    Items<<QString::number(pOrder->VolumeTraded);
	//状态
    switch(pOrder->OrderStatus){
        case    THOST_FTDC_OST_NotTouched:	Items<<QStringLiteral("未报"); break;
        //case 	'1':	Items<<QStringLiteral("待报");break;
        case 	THOST_FTDC_OST_Touched:	//Items<<QStringLiteral("已报");break;
        case 	THOST_FTDC_OST_NoTradeQueueing:	Items<<QStringLiteral("已报");break;
        case 	THOST_FTDC_OST_NoTradeNotQueueing:	Items<<QStringLiteral("部成待撤");break;
        case 	THOST_FTDC_OST_PartTradedNotQueueing:	Items<<QStringLiteral("部撤");break;
        case 	THOST_FTDC_OST_Canceled:	Items<<QStringLiteral("已撤");break;
        case 	THOST_FTDC_OST_PartTradedQueueing:	Items<<QStringLiteral("部成");break;
        case 	THOST_FTDC_OST_AllTraded:	Items<<QStringLiteral("已成");break;
        case 	THOST_FTDC_OST_Unknown:	Items<<QStringLiteral("废单");break;
	}
	
	//委托时间
    Items<<QString(pOrder->InsertTime);

    ///投机套保
    switch(pOrder->CombHedgeFlag[0]){
    case THOST_FTDC_HF_Speculation:
        Items<<QStringLiteral("投机");
        break;
    case THOST_FTDC_HF_Arbitrage:
        Items<<QStringLiteral("套利");
        break;
    case THOST_FTDC_HF_Hedge:
        Items<<QStringLiteral("套保");
        break;
    default:
        break;
    }

#ifdef __DETAILS
    Items<<""<<m_MapUFTSystemRetTime[QString(orderinfo.entrust_no)]<<currtime.split(" ")[1];
#endif

	QTreeWidgetItem* A = new QTreeWidgetItem(Items);
    m_treeWidget->insertTopLevelItem(0,A);

	m_UpdateMutex.unlock();
}
